package com.tanhua.admin.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.tanhua.admin.mapper.AnalysisMapper;
import com.tanhua.commons.utils.DateUtils;
import com.tanhua.dubbo.api.UserApi;
import com.tanhua.model.vo.AnalysisDataVo;
import com.tanhua.model.vo.AnalysisSummaryVo;
import com.tanhua.model.vo.FindData;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service
public class DashboardService {

    @DubboReference
    private UserApi userApi;

    @Autowired
    private AnalysisMapper analysisMapper;

    /**
     * 概要统计信息
     * @return
     */
    public AnalysisSummaryVo summary() {
        //获取当前时间与昨天时间
        //Date currentDate = DateUtil.date(System.currentTimeMillis());
        DateTime currentDate = DateUtil.parseDate("2020-09-06");
        //获取累计用户的总数userCounts
        Integer userCounts = userApi.counts();

        //查询过去30天的活跃用户数
        Integer activePassMonth= analysisMapper.activeUserCounts(currentDate,DateUtil.offsetDay(currentDate, -30));
        //查询过去7天的活跃用户
        Integer activePassWeek=analysisMapper.activeUserCounts(currentDate,DateUtil.offsetDay(currentDate, -7));

        //查询今日新增用户
        Integer newUsersToday=analysisMapper.sumAnalysisToday(currentDate,"num_registered");
        //昨日新增用户  DateUtil.offsetDay(currentDate, 1)
        Integer lastUsersToday=analysisMapper.sumAnalysisToday(DateUtil.offsetDay(currentDate, -1),"num_registered");

        //查询今日登录次数
        Integer loginTimesToday=analysisMapper.sumAnalysisToday(currentDate, "num_login");
        //查询昨日登录次数
        Integer loginTimesYestoday=analysisMapper.sumAnalysisToday(DateUtil.offsetDay(currentDate, -1),"num_login");

        //查询今日活跃用户
        Integer activeUsersToday=analysisMapper.sumAnalysisToday(currentDate,"num_active");
        //查询今日活跃用户
        Integer activeUsersYestoday=analysisMapper.sumAnalysisToday(DateUtil.offsetDay(currentDate, -1),"num_active");

        //分别查询今日新增、今日登录、今日活跃用户的跌涨率，单位百分数
        BigDecimal todayNewcomputeRate = DashboardService .computeRate(newUsersToday, lastUsersToday);
        BigDecimal todayLogincomputeRate = DashboardService .computeRate(loginTimesToday, loginTimesYestoday);
        BigDecimal todayActivecomputeRate = DashboardService .computeRate(activeUsersToday, activeUsersYestoday);
        //组装返回值
        AnalysisSummaryVo analysisSummaryVo = new AnalysisSummaryVo();
        analysisSummaryVo.setCumulativeUsers((long) userCounts);
        analysisSummaryVo.setActivePassMonth((long) activePassMonth);
        analysisSummaryVo.setActiveUsersToday((long) activeUsersToday);
        analysisSummaryVo.setActivePassWeek((long) activePassWeek);
        analysisSummaryVo.setActiveUsersTodayRate(todayActivecomputeRate);
        analysisSummaryVo.setLoginTimesToday((long) loginTimesToday);
        analysisSummaryVo.setNewUsersToday((long) newUsersToday);
        analysisSummaryVo.setNewUsersTodayRate(todayNewcomputeRate);
        analysisSummaryVo.setLoginTimesTodayRate(todayLogincomputeRate);
        return analysisSummaryVo;
    }


    //计算环比  --环比增长：（本期数－上期数）/上期数×100%
    private static BigDecimal computeRate(int current, int last) {
        BigDecimal result;
        if (last == 0) {
            // 当上一期计数为零时，此时环比增长为倍数增长
            result = new BigDecimal((current - last) * 100);
        } else {
            result = BigDecimal.valueOf((current - last) * 100).divide(BigDecimal.valueOf(last), 2, BigDecimal.ROUND_HALF_DOWN);
        }
        return result;
    }


    /**
     * 新增、活跃用户、次日留存率
     * @param sd
     * @param ed
     * @param type
     * @return
     */
    public AnalysisDataVo analysisData(Long sd, Long ed, String type) {
        //将毫秒值转换为日期
        DateTime startDate = DateUtil.date(sd);
        DateTime endDate = DateUtil.date(ed);
        // 日期时间偏移
        //获取本年时间
        DateTime thisYearStartTime = DateUtil.offset(startDate, DateField.YEAR, 0);
        DateTime thisYearEndTime = DateUtil.offset(endDate, DateField.YEAR, 0);
        //将时间转换为String类型
        String thisStartDate = DateUtils.formatDate(thisYearStartTime);
        String thisEndDate = DateUtils.formatDate(thisYearEndTime);
        //获取去年时间
        DateTime lastYearStartTime = DateUtil.offset(startDate, DateField.YEAR, -1);
        DateTime lastYearEndTime = DateUtil.offset(endDate, DateField.YEAR, -1);
        String lastStartDate = DateUtils.formatDate(lastYearStartTime);
        String lastEndDate = DateUtils.formatDate(lastYearEndTime);

        List<Map<String,Object>> thisYear = new ArrayList<>();
        List<Map<String,Object>> lastYear = new ArrayList<>();

        //101 新增 102 活跃用户 103 次日留存率
        if (type!=null && "101".equals(type)){
            newCount(thisStartDate, thisEndDate, lastStartDate, lastEndDate, thisYear, lastYear);
        }else if (type!=null && "102".equals(type)){
            activeCount(thisStartDate, thisEndDate, lastStartDate, lastEndDate, thisYear, lastYear);
        }else if (type!=null && "103".equals(type)){
            retention1dCount(thisStartDate, thisEndDate, lastStartDate, lastEndDate, thisYear, lastYear);
        }
        AnalysisDataVo analysisDataVo = new AnalysisDataVo();
        analysisDataVo.setThisYear(thisYear);
        analysisDataVo.setLastYear(lastYear);
        return analysisDataVo;
    }


    //新增
    public void newCount(String thisStartDate, String thisEndDate, String lastStartDate, String lastEndDate, List<Map<String, Object>> thisYear, List<Map<String, Object>> lastYear) {
        List<FindData> thisNewCount=analysisMapper.analysisData(thisStartDate, thisEndDate);
        for (FindData thisCount : thisNewCount) {
            Map<String,Object> thisMap = new HashMap<>();
            thisMap.put("title",DateUtils.formatDate(thisCount.getRecordDate()));
            thisMap.put("amount",thisCount.getNumRegistered());
            thisYear.add(thisMap);
        }

        List<FindData> lastNewCount=analysisMapper.analysisData(lastStartDate, lastEndDate);
        for (FindData lastCount : lastNewCount) {
            Map<String,Object> lastMap = new HashMap<>();
            lastMap.put("title",DateUtils.formatDate(lastCount.getRecordDate()));
            lastMap.put("amount",lastCount.getNumRegistered());
            lastYear.add(lastMap);
        }
    }

    //活跃用户
    public void activeCount(String thisStartDate, String thisEndDate, String lastStartDate, String lastEndDate, List<Map<String, Object>> thisYear, List<Map<String, Object>> lastYear) {
        List<FindData> thisNewCount=analysisMapper.analysisData(thisStartDate, thisEndDate);
        for (FindData thisCount : thisNewCount) {
            Map<String,Object> thisMap = new HashMap<>();
            thisMap.put("title",DateUtils.formatDate(thisCount.getRecordDate()));
            thisMap.put("amount",thisCount.getNumActive());
            thisYear.add(thisMap);
        }

        List<FindData> lastNewCount=analysisMapper.analysisData(lastStartDate, lastEndDate);
        for (FindData lastCount : lastNewCount) {
            Map<String,Object> lastMap = new HashMap<>();
            lastMap.put("title",DateUtils.formatDate(lastCount.getRecordDate()));
            lastMap.put("amount",lastCount.getNumActive());
            lastYear.add(lastMap);
        }
    }

    //次日留存
    public void retention1dCount(String thisStartDate, String thisEndDate, String lastStartDate, String lastEndDate, List<Map<String, Object>> thisYear, List<Map<String, Object>> lastYear) {
        List<FindData> thisNewCount=analysisMapper.analysisData(thisStartDate, thisEndDate);
        for (FindData thisCount : thisNewCount) {
            Map<String,Object> thisMap = new HashMap<>();
            thisMap.put("title",DateUtils.formatDate(thisCount.getRecordDate()));
            thisMap.put("amount",thisCount.getNumRetention1d());
            thisYear.add(thisMap);
        }

        List<FindData> lastNewCount=analysisMapper.analysisData(lastStartDate, lastEndDate);
        for (FindData lastCount : lastNewCount) {
            Map<String,Object> lastMap = new HashMap<>();
            lastMap.put("title",DateUtils.formatDate(lastCount.getRecordDate()));
            lastMap.put("amount",lastCount.getNumRetention1d());
            lastYear.add(lastMap);
        }
    }


}
